from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from fastapi.responses import FileResponse, JSONResponse
import os

from engine import Game, say

app = FastAPI(title="零号记忆：S-47 的命运 API")

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 静态前端
static_dir = os.path.join(os.path.dirname(__file__), "static")
os.makedirs(static_dir, exist_ok=True)
app.mount("/static", StaticFiles(directory=static_dir), name="static")

# 单实例游戏（可扩展为多会话）
story_path = os.path.join(os.path.dirname(__file__), 'content', 'story.json')

game = Game(story_path)


def current_state():
    # 处理概率事件，直到没有事件触发
    while True:
        chap = game.get_chapter(game.chap)
        if game.roll_prob_event(chap):
            continue
        break
    chap = game.get_chapter(game.chap)
    choices = [c for c in chap.get('choices', []) if game.eval_cond(c.get('require'))]
    return {
        "chapter": game.chap,
        "text": chap.get('text', ''),
        "choices": [{"text": c.get('text', '')} for c in choices],
        "vars": game.vars,
        "achievements": list(game.achieve),
        "is_end": bool(chap.get('is_end')),
    }


@app.get("/")
async def index():
    index_path = os.path.join(static_dir, "index.html")
    return FileResponse(index_path)


@app.get("/api/state")
async def get_state():
    # 如果是结局，记录成就状态
    chap = game.get_chapter(game.chap)
    if chap.get('is_end'):
        game.evaluate_achievements('game_end', {'end_chap': game.chap})
        game.evaluate_achievements('achievements_unlocked')
    return JSONResponse(current_state())


@app.post("/api/choose")
async def post_choose(payload: dict):
    action = payload.get('action')
    if action == 'back':
        game.rollback()
        return JSONResponse(current_state())
    # 过滤可选项
    chap = game.get_chapter(game.chap)
    choices = [c for c in chap.get('choices', []) if game.eval_cond(c.get('require'))]
    if action == 'skip':
        game.evaluate_achievements('skip_used')
        idx = 0
    else:
        idx = int(payload.get('index', 0))
        if idx < 0 or idx >= len(choices):
            return JSONResponse({"error": "选择下标无效"}, status_code=400)
    sel = choices[idx]
    game.history.append({
        'chapter': game.chap,
        'vars': game.vars.copy(),
        'sel_text': sel.get('text', '')
    })
    game.apply_set(sel.get('set', {}))
    nxt = sel.get('next')
    if not game.ensure_chapter_exists(nxt, {'from': game.chap, 'sel_text': sel.get('text','')}):
        say("⚠️ 该分支尚未编写，返回城市入口。")
        nxt = 'city_entry' if game.get_chapter('city_entry') else game.chap
    game.chap = nxt
    game.save()
    return JSONResponse(current_state())


@app.post("/api/rollback")
async def api_rollback():
    game.rollback()
    return JSONResponse(current_state())


@app.post("/api/restart")
async def api_restart():
    global game
    # 重开前删除存档，避免自动读取上次进度
    try:
        save_path = os.path.join(os.path.dirname(__file__), 'save.json')
        if os.path.exists(save_path):
            os.remove(save_path)
    except Exception:
        pass
    game = Game(story_path)
    return JSONResponse(current_state())